/**
 * 폼작성시 활용할 공통함수
 */
//*************************************************************************
// 파라메터에 포함된 정보로 폼엘리먼트 값 설정
// 		- elemName: radio에 대한 지원 (2014-04-23)
//*************************************************************************
function setElemValue(param) {
	function getExpReturn(_info, _data) {
		var exp = _info.exp;
		return (exp ? exp(_data) : _data);
	}
	
	for (var prop in param.data) {
		var info = param.map[prop];
		if (!info) { continue; }
		
		if (typeof info == "function") {
			info(param.data[prop]);
		} else 
		if (typeof info == "object") {
			var elem = info.elem;
			var elemName = info.elemName;
			if (elem && elem.length > 0) {
				// TODO: elem.prop("tagName") 에 따른 처리내용 추가 구현
				switch (elem.prop("tagName").toLowerCase()) {
				case "input":
					// TODO: elem.attr("type") (checkbox, hidden, password, radio, text) 에 따른 처리내용을 추가 구현
					switch (elem.attr("type").toLowerCase()) {
					case "text":
						elem.val(getExpReturn(info, param.data[prop]));
				        break;
					}
					break;
				case "textarea":
					elem.text(getExpReturn(info, param.data[prop]));
					break;
				}
			} else
			if (elemName) {
			    var elems = $("[name='" + elemName + "']");
			    
                switch (elems.prop("tagName").toLowerCase()) {
                case "input":
                    switch (elems.attr("type").toLowerCase()) {
                    case "radio":
                    	$("#" + elemName + param.data[prop]).attr("checked", true);
                    	$("[name='" + elemName + "']:not(#" + elemName + param.data[prop] + ")").attr("checekd", false);
                        break;
                    break;
                    }
                }
			}
		}
	}
}

//*************************************************************************
// 파라메터에 포함된 정보로 ajax 호출
//*************************************************************************
function callAjax(param) {
	var def = param.urls[param.type];
	if (!def) { return; }
	
	var url = def.url;
	var data;
	if (typeof def.data == "function") {
		data = def.data();
	} else {
		data = def.data;
	}
	var onsuccess = def.onsuccess;
	var showAlert = def.showAlert;
	var onvalidate = def.onvalidate;
	
	if (onvalidate) {
		if (!onvalidate()) { return; }
	}
	
	wait();
	
    $.ajax({
    	type: "post",
    	url: url,
    	async: true,
    	contentType: "application/json;charset=utf-8",
        data: JSON.stringify(data),
        dataType: "json",
    	success: function(data, text, request) {
    		unwait();
    		if (showAlert) { alert("정상 처리 되었습니다."); }
    		if (onsuccess) {
    		    onsuccess(data, text, request);
    		}	 
    	},
    	error: function(jqXHR, textStatus, errorThrown) {
    		unwait();
    		alert("처리 중 오류가 발생하였습니다.");
    	}
    });	
}

//*************************************************************************
// 편집버튼 처리 컴포넌트
// 초기화: setupButton("<컴포넌트가 포함될 DIV의 ID>", [<버튼처리정보>]); 
// 버튼처리정보오브젝트:
//*************************************************************************
var buttonManager = {
	$holder: undefined,	
	//*************************************************************************
	// 상세보기: 수정,답글,삭제,목록 
	// 수정: 저장,취소(상세보기로)
	// 등록: 저장,취소(목록의 조회 페이지로)
	// 답글: 저장,취소(목록의 조회 페이지로)
	//*************************************************************************
    setupButton: function(holder, defs) {
    	function doClick(def, state) {
    	    if (!def) { return; }
    	    def.action(state);
    	}    

    	function showHideButton(state) {
    	    var show = defs.states[state].show;
    	    for (var button in defs.buttons) {
    	        var $button = $("#" + button);
    	        if ($.inArray(button, show) > -1) {
    	            $button.show();
    	        } else {
    	            $button.hide();
    	        }
    	    }
    	}

    	this.$holder = $("#" + holder);
    	
    	var initState = defs.getInitState();
    	this.setState(initState);
    	for (var prop in defs.buttons) {
    		// 각 버튼의 클릭이벤트에 핸들러 지정
    		$("#" + prop).bind("click", function() {
    			var def = defs.buttons[this.id];
    			doClick(def, buttonManager.getState());
    			if (def.afterState) {
    				showHideButton(def.afterState);
    				buttonManager.setState(def.afterState);
    			}
    		});
    	}
    	
    	// 비지니스 주 흐름은 버튼을 클릭하면 상태가 변동, 
    	// 초기화의 경우에는 상태를 먼저 결정하고, 이 상태의 수행 함수 실행  
    	showHideButton(initState);
    	var stateDef = defs.states[initState];
    	if (stateDef.actionOnInit) {
    		stateDef.actionOnInit();
    	}
    	return initState;
    },
    getState: function() {
    	return this.$holder.attr("state");
    },
    setState: function(state) {
    	this.$holder.attr("state", state);
    }
};	

//*************************************************************************
// 파일 업로드 컴포넌트
// 초기화: fileUploader("<컴포넌트가 포함될 DIV의 ID>", [<초기파일목록>], "<파일업로드 수행 URL>"); 
// 파일오브젝트:
//		{tp: "<old:기존파일, new:새로선택된파일, del.old:기존파일삭제, del.new:새로선택된파일삭제>",
//			file: {
//				ext: "<확장자>",
//				name: "<경로명을 제외한 파일명>",
//				newName: "<경로명을 제외한 저장파일명>",
//				size: <바이트단위의 파일 크기>
//			}}
// 서버응답데이터: IE8에서의 호환성을 위해서 text/plain형식으로 javascript 오브젝트 문자열을 이용
// 업로드결과데이터: getFiles() 호출시 파일오브젝트 반환
//*************************************************************************
var fileUploader = {
	$div: undefined,	
	// 초기화
	setupUploader: function(div, initFiles, url) {
		this.$div = $("#" + div);
		
		if (this.$div.length == 0) { return; }
		
		this.$div.append("<span class='file-upload-button btn btn-success fileinput-button'>"
				+ "<label for='fileupload' style='cursor:pointer'>파일선택...</label><input id='fileupload' type='file' name='file' style='width:0px;height:0px;'/>"
				+ "</span><br/><span id='filename'></span>");
		this.$div.data("file-list", []);
		
		for (var i = 0; initFiles && i < initFiles.length; i++) {
			this.addFileDesc(initFiles[i], "old");
		}
		
	    $("#fileupload").fileupload({
	    	dropZone: null,
	    	pasteZone: null,
	        add: function(e, data) {
	            if (data.files.length > 0) {
	                var size = data.files[0].size;
	                if (!size && size >= 10000000) { alert("파일크기가 초과되었습니다."); return; }
	            }
	            
	            var list = fileUploader.$div.data("file-list");
	            for (var i = 0; list && i < list.length; i++) {
	            	if (list[i].file.name == data.files[0].name && $.inArray(list[i].tp, ["old", "new"]) > -1) { alert("동일한 이름의 파일이 이미 선택되었습니다."); return; }
	            }
	            
	            data.submit(); 
	        },    	
	        url: url,
	        dataType: "text",
	        done: function (e, data) {
	        	if (data.result) {
		            var jsonData = $.parseJSON(data.result);
		            
		            if (jsonData.state && jsonData.state == "fail") {
		            	alert(jsonData.message);
		            } else {
			            $.each(jsonData, function (index, file) {
			            	fileUploader.addFileDesc(file, "new");
			            });
		            };
	        	} else {
	                alert("처리 중 오류가 발생하였습니다.");
	        	}
	        },
	        fail: function(e, data) {
	            if (data.jqXHR.responseText) {
	            	var result = $.parseJSON(data.jqXHR.responseText);
	                alert(result.message); 
	            } else {
	                alert("처리 중 오류가 발생하였습니다.");
	            }
	        }	        
	    }).prop('disabled', !$.support.fileInput)
	        .parent().addClass($.support.fileInput ? undefined : 'disabled');		
	},
	
	// 임시업로드된 파일의 정보를 표시하는 엘리먼트의 HTML
	getFileHtml: function(file) {
	    var html = "<span class='ui-widget' css-tag='span-file' data-tag='file' id='{new.name}'>{file}&nbsp;({size}K)&nbsp;"
	        + "<button class='ui-button ui-widget ui-state-default ui-corner-all' css-tag='button'><span class='ui-icon ui-icon-closethick'/></button>"
	        + "</span>";
	        
	    html = html.replace("{new.name}", file.newName).replace("{file}", file.name).replace("{size}", (file.size / 1000).toFixed(2));
	    return html;
	},
	
	// 임시업로드된 파일의 정보를 데이터에 반영하고 화면에 표시할 엘리먼트 생성
	addFileDesc: function(file, tp) {
	    var $elem = $(this.getFileHtml(file));
	    var data = this.$div.data("file-list");
	    data.push({tp:tp, file:file});
	    
	    $elem.find("[css-tag='button']").bind("click", function() {
	    	var newName = $elem.attr("id");
	    	
	    	var data = fileUploader.$div.data("file-list");
	    	var tp = "";
	    	for (var i = 0; data && i < data.length; i++) {
	    		if (data[i].file.newName == newName) {
	    			if ($.inArray(data[i].tp, ["old", "new"]) > -1) {
	    				tp = "del." + data[i].tp;
	    			}
	    			data.push({tp:tp, file:data[i].file});
	    			if ($.inArray(data[i].tp, ["old", "new"]) > -1) {
	    				data.splice(i, 1);
	    			}
	    			break;
	    		} 
	    	}
	    	
	        $(this).parent().remove(); // 업로드 파일 정보를 삭제한다.
	    });
	    $("#filename").append($elem);
	},
	
	// 임시업로드된 파일정보의 반환
	getFiles: function() {
		return this.$div.data("file-list");
	}
}
